home *** CD-ROM | disk | FTP | other *** search
/ Aminet 16 / Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso / Aminet / comm / term / term_source.lha / Extras / Source / term-source.lha / Glue / StackCall.asm < prev    next >
Assembly Source File  |  1996-10-20  |  4KB  |  182 lines

  1. **
  2. **    StackCall.asm
  3. **
  4. **    Stack swap & stack size check routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9.  
  10.     include    "exec/types.i"
  11.     include    "exec/tasks.i"
  12.     include    "exec/memory.i"
  13.     include    "exec/execbase.i"
  14.  
  15.     include    "dos/dos.i"
  16.     include    "dos/dosextens.i"
  17.  
  18. *----------------------------------------------------------------------
  19.  
  20. CALL    macro
  21.     xref    _LVO\1
  22.     jsr    _LVO\1(a6)
  23.     endm
  24.  
  25. *----------------------------------------------------------------------
  26.  
  27. ARG_SUCCESS    equ    4+5*4
  28. ARG_STACKSIZE    equ    ARG_SUCCESS+4
  29. ARG_ARGCOUNT    equ    ARG_STACKSIZE+4
  30. ARG_ROUTINE    equ    ARG_ARGCOUNT+4
  31. ARG_ARGS    equ    ARG_ROUTINE+4
  32.  
  33. TRUE        equ    1
  34. FALSE        equ    0
  35.  
  36. *----------------------------------------------------------------------
  37.  
  38.     section    text,code
  39.  
  40. *----------------------------------------------------------------------
  41.  
  42.     xdef    _StackCall
  43.  
  44.     ;    LONG __stdargs StackCall(    LONG *Success,
  45.     ;                    LONG StackSize,
  46.     ;                    LONG ArgCount,
  47.     ;                    LONG (* __stdargs Function)(...),
  48.     ;                    ...);
  49.     ;
  50.     ;    Calls a function with parameters on a newly-allocated
  51.     ;    stack. Caution: assumes all arguments are 32 bits wide.
  52.  
  53. _StackCall:
  54.  
  55.     movem.l    d2/d3/a2/a3/a6,-(sp)        ; Save registers
  56.  
  57.     move.l    ARG_STACKSIZE(sp),d0        ; Get desired stack size
  58.     add.l    #15+StackSwapStruct_SIZEOF,d0    ; Round to next...
  59.     and.l    #-16,d0                ; ...quad long word
  60.     move.l    d0,d2                ; Save it for later
  61.     move.l    #MEMF_PUBLIC,d1            ; Well?
  62.     move.l    _SysBase,a6            ; Get SysBase
  63.  
  64.     CALL    AllocMem            ; Allocate the memory
  65.     tst.l    d0                ; Success?
  66.     beq.b    1$                ; Exit if not
  67.  
  68.     move.l    d0,a2                ; Remember base adress
  69.  
  70.     add.l    #StackSwapStruct_SIZEOF,d0    ; Skip the header
  71.     move.l    d0,stk_Lower(a2)        ; Store the stack lower bound
  72.  
  73.     move.l    a2,a3                ; Get the base address
  74.     add.l    d2,a3                ; Add the allocation size
  75.     move.l    a3,stk_Upper(a2)        ; Store the stack upper bound
  76.  
  77.     move.l    ARG_ARGCOUNT(sp),d0        ; Get the number of arguments
  78.     beq.b    3$                ; Skip if none
  79.  
  80.     moveq    #4,d1                ; One long word per argument
  81.     mulu    d0,d1                ; Nasty
  82.     ext.l    d1                ; Forget the upper word
  83.     addq.l    #4,d1                ; One for predecrement
  84.     sub.l    d1,a3                ; Pull it down
  85.  
  86.     subq.l    #1,d0                ; Subtract one for DBRA
  87.     lea.l    ARG_ARGS(sp),a0            ; Get the source argument list
  88.     move.l    a3,a1                ; Get the destination argument list
  89.  
  90. 2$    move.l    (a0)+,(a1)+            ; Copy the parameters
  91.     dbra    d0,2$                ; Loop until all is copied
  92.  
  93. 3$    move.l    a3,stk_Pointer(a2)        ; Store the new stack pointer
  94.  
  95.     move.l    ARG_ROUTINE(sp),a3        ; Get address of the routine to call
  96.  
  97.     move.l    a2,a0                ; Swap the stack
  98.     CALL    StackSwap
  99.  
  100.     jsr    (a3)                ; Call the routine
  101.     move.l    d0,d3                ; Save the result
  102.  
  103.     move.l    a2,a0                ; Swap the stack
  104.     CALL    StackSwap
  105.  
  106.     move.l    a2,a1                ; Get the base address
  107.     move.l    d2,d0                ; Get the allocation length
  108.     CALL    FreeMem                ; Free the memory
  109.  
  110.     move.l    ARG_SUCCESS(sp),a0        ; Flag as success
  111.     move.l    #TRUE,(a0)
  112.  
  113.     move.l    d3,d0                ; Return the result
  114.  
  115.     movem.l    (sp)+,d2/d3/a2/a3/a6        ; Restore registers
  116.     rts
  117.  
  118. 1$    move.l    ARG_SUCCESS(sp),a0        ; Flag as failure
  119.     move.l    #FALSE,(a0)
  120.  
  121.     movem.l    (sp)+,d2/d3/a2/a3/a6        ; Restore registers
  122.     rts
  123.  
  124. *----------------------------------------------------------------------
  125.  
  126.     xdef    @StackSize
  127.     xdef    _StackSize
  128.  
  129.     ;    LONG StackSize(struct Task *Task);
  130.     ;
  131.     ;    Determines the amount of stack still available to a task.
  132.     ;    Pass in NULL as the task address to return the amount
  133.     ;    of stack available to the calling task.
  134.  
  135. _StackSize:
  136.     move.l    4(sp),a0            ; Get task address
  137.  
  138. @StackSize:
  139.     move.l    a6,-(sp)            ; Save registers
  140.  
  141.     move.l    _SysBase,a6            ; Get SysBase
  142.  
  143.     move.l    a0,d0                ; Valid task address?
  144.     beq.b    4$
  145.  
  146.     move.l    TC_SPREG(a0),d0            ; Remember stack pointer
  147.     bra.b    3$
  148.  
  149. 4$    move.l    a0,a1
  150.     CALL    FindTask            ; Who am I?
  151.     move.l    d0,a0                ; That's me
  152.     move.l    sp,d0                ; Remember stack pointer
  153.  
  154. 3$    cmp.b    #NT_PROCESS,LN_TYPE(a0)        ; Is this a process?
  155.     bne.b    1$
  156.  
  157.     tst.l    pr_CLI(a0)            ; Is it running as a CLI process?
  158.     beq.b    1$
  159.  
  160.     move.l    pr_ReturnAddr(a0),d1        ; Get upper bound
  161.     addq.l    #4,d1
  162.     move.l    pr_ReturnAddr(a0),a0
  163.     sub.l    (a0),d1                ; Subtract total stack size
  164.  
  165.     bra.b    2$
  166.  
  167. 1$    move.l    TC_SPLOWER(a0),d1        ; Get lower bound
  168.  
  169. 2$    sub.l    d1,d0                ; Subtract from stack pointer
  170.  
  171.     move.l    (sp)+,a6            ; Restore registers
  172.  
  173.     rts
  174.  
  175. *----------------------------------------------------------------------
  176.  
  177.     section    data,data
  178.  
  179.     xref    _SysBase
  180.  
  181.     end
  182.